package com.zp.business.impl.lab;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zp.base.api.RemoteSerialNumberUtils;
import com.zp.business.entity.clinicOrder.ClinicOrders;
import com.zp.business.entity.clinicOrder.ClinicOrdersCost;
import com.zp.business.entity.clinicOrder.OutpTreatRec;
import com.zp.business.entity.clinicOrder.bo.ApplyItemBo;
import com.zp.business.entity.clinicOrder.bo.ClinicOrderParam;
import com.zp.business.entity.clinicOrder.bo.ClinicOrdersBo;
import com.zp.business.entity.lab.LabApply;
import com.zp.business.entity.lab.LabItem;
import com.zp.business.entity.lab.bo.GroupByLabTubeApply;
import com.zp.business.entity.lab.bo.LabApplyBo;
import com.zp.business.entity.lab.bo.LabItemBo;
import com.zp.business.entity.lab.bo.SaveParamBo;
import com.zp.business.entity.lab.vo.LabApplyVo;
import com.zp.business.entity.outpFees.OutpFeesDetail;
import com.zp.business.entity.outpFees.bo.OutpFeesMasterBo;
import com.zp.business.mapper.clinicOrder.ClinicOrdersCostMapper;
import com.zp.business.mapper.clinicOrder.ClinicOrdersMapper;
import com.zp.business.mapper.clinicOrder.OutpTreatRecMapper;
import com.zp.business.mapper.lab.LabApplyMapper;
import com.zp.business.mapper.lab.LabItemMapper;
import com.zp.business.mapper.outpFees.OutpFeesDetailMapper;
import com.zp.business.service.clinicOrder.IClinicOrdersService;
import com.zp.business.service.clinicOrder.IOutpTreatRecService;
import com.zp.business.service.lab.ILabApplyService;
import com.zp.business.service.lab.ILabItemService;
import com.zp.business.service.outpFees.IOutpFeesMasterService;
import com.zp.business.service.patient.IClinicMasterService;
import com.zp.common.core.constant.BaseConstants;
import com.zp.common.core.constant.CacheNames;
import com.zp.common.core.constant.UserConstants;
import com.zp.common.core.utils.DateUtils;
import com.zp.common.core.utils.StringUtils;
import com.zp.common.myBatis.core.page.PageQuery;
import com.zp.common.myBatis.core.page.TableDataInfo;
import com.zp.common.redis.utils.CacheUtils;
import com.zp.common.satoken.utils.LoginHelper;
import com.zp.system.api.RemoteOrgDictDataService;
import com.zp.system.api.entity.SysDept;
import com.zp.system.api.entity.SysOrgDict;
import com.zp.system.api.entity.SysUser;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 检验申请主Service业务层处理
 *
 * @author zhang peng
 * @ date 2024-03-05
 */
@RequiredArgsConstructor
@Service
public class LabApplyServiceImpl implements ILabApplyService {

    private final LabApplyMapper baseMapper;

    private final ILabItemService labItemService;
    @DubboReference
    private RemoteSerialNumberUtils remoteSerialNumberUtils;
    //    @DubboReference
//    private RemoteOutpFeesMasterService remoteOutpFeesMasterService;
    private final IOutpFeesMasterService outpFeesMasterService;
    @DubboReference
    private RemoteOrgDictDataService orgDictDataService;
    private final IClinicOrdersService clinicOrdersService;
    private final IOutpTreatRecService outpTreatRecService;
    private final IClinicMasterService clinicMasterService;
    private final ClinicOrdersCostMapper clinicOrdersCostMapper;
    private final ClinicOrdersMapper clinicOrdersMapper;
    private final OutpFeesDetailMapper outpFeesDetailMapper;
    private final OutpTreatRecMapper outpTreatRecMapper;
    private final LabItemMapper labItemMapper;

    /**
     * 用户信息
     */
    static Map<String, SysUser> sysUserMap = CacheUtils.get(CacheNames.SYS_USER);

    static Map<String, SysDept> sysDeptMap = CacheUtils.get(CacheNames.SYS_DEPT);
//    static Map<String, Labtype> examTypeVoMap = CacheUtils.get(CacheNames.EXAM_TYPE);

    /**
     * 查询检验申请主
     */
    @Override
    public LabApplyVo queryById(String id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询检验申请主列表(分页)
     */
    @Override
    public TableDataInfo<LabApplyVo> queryPageList(LabApplyBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<LabApply> lqw = buildQueryWrapper(bo);
        Page<LabApplyVo> result = new Page<>();
        if (StringUtils.equals(bo.getInoroutFlag(), BaseConstants.IS_CLINIC)) {
            result = baseMapper.selectVoPage(pageQuery.build(), bo);
        } else {

        }
        result.getRecords().forEach(item -> {
            item.setImplementDeptName(StringUtils.isNotBlank(item.getImplementDept()) ? sysDeptMap.get(item.getImplementDept()).getDeptName() : "");
            item.setApplyDeptName(StringUtils.isNotBlank(item.getApplyDept()) ? sysDeptMap.get(item.getApplyDept()).getDeptName() : "");
            item.setConfirmUserName(StringUtils.isNotBlank(item.getConfirmUser()) && StringUtils.isNotBlank(item.getConfirmUser())
                    ? sysUserMap.get(item.getConfirmUser()).getNickName() : "");
            item.setCancelConfirmUserName(StringUtils.isNotBlank(item.getCancelConfirmUser()) && StringUtils.isNotBlank(item.getCancelConfirmUser())
                    ? sysUserMap.get(item.getCancelConfirmUser()).getNickName() : "");
//            item.setLabTypeName(StringUtils.isNotBlank(item.getlab()) ? examTypeVoMap.get(item.getExamType()).getName() : "");
            LabItemBo labItemBo = new LabItemBo();
            labItemBo.setOrgId(item.getOrgId());
            labItemBo.setApplyId(item.getId());
            labItemBo.setDelFlag("0");
            item.setLabItemVoList(labItemService.queryList(labItemBo));
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询检验申请主列表(不分页)
     */
    @Override
    public List<LabApplyVo> queryList(LabApplyBo bo) {
        LambdaQueryWrapper<LabApply> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<LabApply> buildQueryWrapper(LabApplyBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<LabApply> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getClinicId()), LabApply::getClinicId, bo.getClinicId());
        lqw.eq(StringUtils.isNotBlank(bo.getApplyDept()), LabApply::getApplyDept, bo.getApplyDept());
        lqw.eq(StringUtils.isNotBlank(bo.getApplyNo()), LabApply::getApplyNo, bo.getApplyNo());
        lqw.eq(StringUtils.isNotBlank(bo.getPatientId()), LabApply::getPatientId, bo.getPatientId());
        lqw.eq(StringUtils.isNotBlank(bo.getInoroutFlag()), LabApply::getInoroutFlag, bo.getInoroutFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getConfirmFlag()), LabApply::getConfirmFlag, bo.getConfirmFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getConfirmUser()), LabApply::getConfirmUser, bo.getConfirmUser());
        lqw.eq(StringUtils.isNotBlank(bo.getCancelConfirmUser()), LabApply::getCancelConfirmUser, bo.getCancelConfirmUser());
        lqw.eq(StringUtils.isNotBlank(bo.getChargeFlag()), LabApply::getChargeFlag, bo.getChargeFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getImplementDept()), LabApply::getImplementDept, bo.getImplementDept());
        lqw.eq(StringUtils.isNotBlank(bo.getIsUrgent()), LabApply::getIsUrgent, bo.getIsUrgent());
        lqw.eq(StringUtils.isNotBlank(bo.getSpecimen()), LabApply::getSpecimen, bo.getSpecimen());
        lqw.eq(StringUtils.isNotBlank(bo.getSpecimenExplain()), LabApply::getSpecimenExplain, bo.getSpecimenExplain());
        lqw.eq(StringUtils.isNotBlank(bo.getOrgId()), LabApply::getOrgId, bo.getOrgId());
        lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), LabApply::getRemarks, bo.getRemarks());
        lqw.eq(StringUtils.isNotBlank(bo.getVisitId()), LabApply::getVisitId, bo.getVisitId());
        lqw.eq(StringUtils.isNotBlank(bo.getClinicOrdersId()), LabApply::getClinicOrdersId, bo.getClinicOrdersId());
        lqw.eq(StringUtils.isNotBlank(bo.getIsPhy()), LabApply::getIsPhy, bo.getIsPhy());
        lqw.eq(StringUtils.isNotBlank(bo.getResultStatus()), LabApply::getResultStatus, bo.getResultStatus());
        lqw.eq(bo.getResultsRptDateTime() != null, LabApply::getResultsRptDateTime, bo.getResultsRptDateTime());
        lqw.eq(StringUtils.isNotBlank(bo.getTranscriptionist()), LabApply::getTranscriptionist, bo.getTranscriptionist());
        lqw.eq(StringUtils.isNotBlank(bo.getNaYaoTiShi()), LabApply::getNaYaoTiShi, bo.getNaYaoTiShi());
        lqw.eq(StringUtils.isNotBlank(bo.getJianYi()), LabApply::getJianYi, bo.getJianYi());
        lqw.eq(StringUtils.isNotBlank(bo.getSampleId()), LabApply::getSampleId, bo.getSampleId());
        lqw.eq(StringUtils.isNotBlank(bo.getAuditor()), LabApply::getAuditor, bo.getAuditor());
        lqw.eq(StringUtils.isNotBlank(bo.getNotes()), LabApply::getNotes, bo.getNotes());
        lqw.eq(bo.getConfirmDate() != null, LabApply::getConfirmDate, bo.getConfirmDate());
        lqw.eq(StringUtils.isNotBlank(bo.getConfirmCancelFlag()), LabApply::getConfirmCancelFlag, bo.getConfirmCancelFlag());
        lqw.eq(bo.getRealDate() != null, LabApply::getRealDate, bo.getRealDate());
        lqw.orderByDesc(LabApply::getRealDate);
        return lqw;
    }

    /**
     * 新增检验申请主
     */
    @Override
    public Boolean insertByBo(LabApplyBo bo) {
        LabApply add = BeanUtil.toBean(bo, LabApply.class);
        validEntityBeforeSave(add);
        add.initEntity();
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改检验申请主
     */
    @Override
    public Boolean updateByBo(LabApplyBo bo) {
        LabApply update = BeanUtil.toBean(bo, LabApply.class);
        update.updateInfo();
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(LabApply entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除检验申请主
     */
    @Override
    public int deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        for (String id : ids) {
            Map<String, Object> validateMap = validate(id);
            if ((Integer) validateMap.get("key") != 0) {
                return (Integer) validateMap.get("key");
            }
            LabApplyVo labApplyVo = (LabApplyVo) validateMap.get("labApplyVo");
            // 删除门诊处置治疗项目
            Boolean b = outpTreatRecService.deleteByBo(labApplyVo.getOrgId(), labApplyVo.getApplyNo());
            Boolean b1 = clinicOrdersService.deleteByBo(labApplyVo.getOrgId(), labApplyVo.getApplyNo());
            Boolean b2 = labItemService.deleteByBo(labApplyVo.getId());
            Boolean b3 = baseMapper.deleteById(labApplyVo.getId()) > 0;
            if (b && b1 && b2 && b3) {
                return 1;
            }
        }
        return 0;
    }

    private Map<String, Object> validate(String id) {
        LabApplyVo labApplyVo = baseMapper.selectVoById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("key", 0);
        map.put("labApplyVo", labApplyVo);
        if (ObjectUtil.isEmpty(labApplyVo)) {
            // 数据不存在
            map.put("key", 999);
        } else if (StringUtils.equals(labApplyVo.getConfirmFlag(), UserConstants.YES)) {
            // 已确认
            map.put("key", 998);
        } else if (StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.TWO)) {
            // 已收费
            map.put("key", 992);
        } else if (StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.THREE)) {
            // 申请退费
            map.put("key", 993);
        } else if (StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.FOUR)) {
            // 已退费
            map.put("key", 994);
        } else if (StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.FIVE)) {
            // 确认退费
            map.put("key", 995);
        } else if (StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.SIX)) {
            // 科室确认退费中
            map.put("key", 996);
        }
        return map;
    }

    @Override
    @GlobalTransactional
    public boolean saveLabApplyAndItem(SaveParamBo bo) {
        // 获取分单后的apply主表list
        List<GroupByLabTubeApply> saveCountApplyList = bo.getGroupByLabTubeApplyList();
        if (CollectionUtils.isNotEmpty(saveCountApplyList)) {
            saveCountApplyList.forEach(countApply -> {
                LabApply labApply = initLabApply(bo, countApply);
                // 诊疗项目id集合
                List<String> itemClinicIds = new ArrayList<>();
                // 组织、保存项目明细
                List<LabItem> labItemList = labItemService.initLabItemAndSave(labApply, countApply.getGroupByLabTubeList());
                // 组织门诊待收费信息数据（clinicOrder、clinicOrderCost）等信息
                ClinicOrderParam clinicOrderParam = new ClinicOrderParam();
                // 设置是否为附加费用(否)
                clinicOrderParam.setWhetherToComeInAttached(UserConstants.NO);
                // 设置诊疗项目类型
                clinicOrderParam.setItemClass(BaseConstants.ITEM_CLASS.LAB);
                List<ApplyItemBo> applyItemBoList = new ArrayList<>();
                // 保存检查项目明细
                labItemList.forEach(labItem -> {
                    ApplyItemBo applyItemBo = new ApplyItemBo();
                    applyItemBo.setApplyItemId(labItem.getId());
                    applyItemBo.setClinicItemId(labItem.getClinicItemId());
                    applyItemBo.setItemClass(BaseConstants.ITEM_CLASS.EXAM);
                    applyItemBo.setNum(labItem.getNum());
                    applyItemBoList.add(applyItemBo);
                });
                LabApplyVo labApplyVo = BeanUtil.toBean(labApply, LabApplyVo.class);
                clinicOrderParam.setApplyItemBoList(applyItemBoList);
                clinicOrderParam.setClinicId(bo.getClinicId());
                clinicOrderParam.setPatientId(bo.getPatientId());
                clinicOrderParam.setDiagnosis(bo.getClinicalDiag());
                clinicOrderParam.setOrgId(labApplyVo.getOrgId());
                clinicOrderParam.setIsApply(UserConstants.YES);
                clinicOrderParam.setApplyNo(labApplyVo.getApplyNo());
                clinicOrderParam.setApplyUser(labApplyVo.getApplyUser());
                clinicOrderParam.setApplyDept(labApplyVo.getApplyDept());
                clinicOrderParam.setImplementUser(labApplyVo.getImplementUser());
                clinicOrderParam.setImplementDept(labApplyVo.getImplementDept());
                clinicOrderParam.setInoroutFlag(labApplyVo.getInoroutFlag());
                clinicOrderParam.setAbidance(1);
                clinicOrderParam.setNum(1);
                bo.setApplyNo(labApplyVo.getApplyNo());
                // 保存clinicOrder、clinicOrderCost信息
                ClinicOrders clinicOrders = clinicOrdersService.initClinicOrders(clinicOrderParam);
                // 更新主表中门诊医嘱id（clinic_orders_id）
                baseMapper.update(null, new LambdaUpdateWrapper<LabApply>()
                        .set(LabApply::getClinicOrdersId, clinicOrders.getId())
                        .eq(LabApply::getId, labApplyVo.getId()));
                // 新增处置治疗信息 start
                clinicOrderParam.setClinicOrdersId(clinicOrders.getId());
                clinicOrderParam.setGroupNo(clinicOrders.getGroupNo());
                outpTreatRecService.saveByBo(clinicOrderParam);
                // 新增处置治疗信息 end
                // 保存耗材
                if (countApply.getCount() != 0) {
                    saveLabBloodFee(bo, countApply.getLabTube(), countApply.getCount(), "lab_tube");
                }
            });
            //采血费
            if (!StringUtils.equals(bo.getIsBloodCollection(), BaseConstants.BLOOD_COLLECTION.NO_BLOOD)) {
                // 保存采血费、采血管费用
                saveLabBloodFee(bo, bo.getIsBloodCollection(), 1, bo.getBloodType());
            }
            //修改接诊医生doctor_id
            if (StringUtils.equals(bo.getInoroutFlag(), BaseConstants.IS_CLINIC)) {
                clinicMasterService.updateDoctorId(bo.getClinicId(), bo.getIsUpdateDoctorId());
            }
            return true;
        }
        return false;
    }


    /**
     * 保存采血费、采血管等耗材费用
     *
     * @param bo        检验主信息
     * @param dictValue 机构字典值
     * @param amount    耗材或采血费数量
     * @return
     */
    public Boolean saveLabBloodFee(SaveParamBo bo, String dictValue, int amount, String dictType) {
        SysOrgDict sysOrgDict = new SysOrgDict();
        sysOrgDict.setOrgId(bo.getOrgId());
        sysOrgDict.setType(dictType);
        sysOrgDict.setValue(dictValue);
        // 组织门诊待收费信息数据（clinicOrder、clinicOrderCost）等信息
        ClinicOrderParam clinicOrderParam = new ClinicOrderParam();
        clinicOrderParam.setNum(1);
        clinicOrderParam.setIsApply(UserConstants.YES);
        // 设置检查单号
        // 设置检查单号
        clinicOrderParam.setApplyNo(remoteSerialNumberUtils.generateOutpTreatNo(bo.getOrgId()));
        commonClinicOrderParam(clinicOrderParam, bo);
        // 设置是否为附加费用(是)
        clinicOrderParam.setWhetherToComeInAttached(UserConstants.YES);
        // 保存clinicOrder、clinicOrderCost信息
        List<SysOrgDict> sysOrgDictList = orgDictDataService.selectList(sysOrgDict);
        if (CollectionUtils.isNotEmpty(sysOrgDictList)) {
            List<ApplyItemBo> applyItemBoList = new ArrayList<>();
            sysOrgDictList.forEach(sysOrgDict1 -> {
                ApplyItemBo applyItemBo = new ApplyItemBo();
                applyItemBo.setClinicItemId(sysOrgDict1.getClinicItemId());
                applyItemBo.setNum(amount);
                applyItemBoList.add(applyItemBo);
            });
            clinicOrderParam.setApplyItemBoList(applyItemBoList);
        }
        ClinicOrders clinicOrders = clinicOrdersService.initClinicOrders(clinicOrderParam);
        // 新增处置治疗信息 start
        clinicOrderParam.setClinicOrdersId(clinicOrders.getId());
        clinicOrderParam.setGroupNo(clinicOrders.getGroupNo());
        List<OutpTreatRec> outpTreatRecs = outpTreatRecService.saveByBo(clinicOrderParam);
        String outpTreatId = outpTreatRecs.get(0).getId();
        clinicOrdersCostMapper.update(null, Wrappers.<ClinicOrdersCost>lambdaUpdate()
                .set(ClinicOrdersCost::getApplyItemId, outpTreatId)
                .eq(ClinicOrdersCost::getOrdersId, clinicOrders.getId())
        );
        outpTreatRecService.update(Wrappers.<OutpTreatRec>lambdaUpdate()
                .set(OutpTreatRec::getApplyItemId, outpTreatId)
                .eq(OutpTreatRec::getId, outpTreatId)
        );
        return false;
    }

    /**
     * 组装公共的clinicOrder信息
     *
     * @param clinicOrderParam
     * @param bo
     */
    private void commonClinicOrderParam(ClinicOrderParam clinicOrderParam, SaveParamBo bo) {
        clinicOrderParam.setClinicId(bo.getClinicId());
        clinicOrderParam.setPatientId(bo.getPatientId());
        clinicOrderParam.setDiagnosis(bo.getClinicalDiag());
        clinicOrderParam.setOrgId(bo.getOrgId());
        clinicOrderParam.setIsApply(UserConstants.YES);
        clinicOrderParam.setApplyUser(LoginHelper.getUserId());
        clinicOrderParam.setApplyDept(LoginHelper.getDeptId());
        clinicOrderParam.setImplementDept(bo.getImplementDept());
        clinicOrderParam.setInoroutFlag(bo.getInoroutFlag());
    }

    /**
     * 组织主表信息
     *
     * @param groupByLabTubeApply
     * @return
     */
    public LabApply initLabApply(SaveParamBo bo, GroupByLabTubeApply groupByLabTubeApply) {
        LabApply labApply = BeanUtil.toBean(groupByLabTubeApply, LabApply.class);
        labApply.initEntity();
        labApply.setClinicId(bo.getClinicId());
        labApply.setPatientId(bo.getPatientId());
        labApply.setInoroutFlag(bo.getInoroutFlag());
        labApply.setOrgId(bo.getOrgId());
        labApply.setSymptom(bo.getSymptom());
        labApply.setRelevantDiag(bo.getRelevantDiag());
        labApply.setSign(bo.getSign());
        labApply.setIsUrgent(bo.getIsUrgent());
        labApply.setClinicalDiag(bo.getClinicalDiag());
        // 设置收费类型： 未收费 1
        labApply.setChargeFlag(BaseConstants.CHARGE_FLAG_DICT.ONE);
        // 设置确认类型： 未确认 1
        labApply.setConfirmFlag(BaseConstants.CONFIRM_FLAG.UNISSUED);
        // 设置检查单号
        labApply.setApplyNo(remoteSerialNumberUtils.generateLabNo(BaseConstants.IS_CLINIC, labApply.getOrgId()));
        labApply.initEntity();
        labApply.setIsPhy(UserConstants.NO);
        labApply.setRealDate(new Date());
        // 设置开单科室
        labApply.setApplyDept(LoginHelper.getDeptId());
        labApply.setApplyUser(LoginHelper.getUserId());
        labApply.setImplementDept(bo.getImplementDept());
        labApply.setImplementUser(bo.getImplementUser());
        baseMapper.insert(labApply);
        return labApply;
    }

    /**
     * 修改收费状态 ：3->申请退费 ;2->撤销退费
     *
     * @param id         exam_apply 主键
     * @param chargeFlag
     * @return
     */
    @Override
    @GlobalTransactional
    public Boolean refundApplication(String id, String chargeFlag) {
        LabApplyVo vo = baseMapper.selectVoById(id);
        if (ObjectUtil.isNotNull(vo)) {
            if (StringUtils.equals(chargeFlag, BaseConstants.CHARGE_FLAG_DICT.TWO)) {
                // 申请退费
                if (!StringUtils.equals(vo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.THREE)) {
                    throw new RuntimeException("申请单状态已改变，申请退费失败请刷新列表。");
                }
            } else if (StringUtils.equals(chargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)) {
                // 撤销退费
                if (!StringUtils.equals(vo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.TWO)) {
                    throw new RuntimeException("申请单状态已改变，撤销退费失败请刷新列表。");
                }
            }
            // 修改主记录
            boolean b = baseMapper.update(null, new LambdaUpdateWrapper<LabApply>()
                    .set(LabApply::getChargeFlag, chargeFlag)
                    .eq(LabApply::getId, id)) > 0;
            // 修改门诊医嘱记录
            LambdaUpdateWrapper<ClinicOrders> ordersLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            ordersLambdaUpdateWrapper.set(ClinicOrders::getChargeFlag, chargeFlag);
            ordersLambdaUpdateWrapper.eq(ClinicOrders::getId, vo.getClinicOrdersId());
            ClinicOrdersBo clinicOrdersBo = new ClinicOrdersBo();
            clinicOrdersBo.setChargeFlag(chargeFlag);
            clinicOrdersBo.setId(vo.getClinicOrdersId());
            boolean b1 = clinicOrdersService.updateChargeFlag(clinicOrdersBo);
            // 修改门诊诊疗项目记录
            LambdaUpdateWrapper<OutpTreatRec> outpTreatRecLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            outpTreatRecLambdaUpdateWrapper.set(OutpTreatRec::getChargeFlag, chargeFlag);
            outpTreatRecLambdaUpdateWrapper.eq(OutpTreatRec::getOrgId, vo.getOrgId());
            outpTreatRecLambdaUpdateWrapper.eq(OutpTreatRec::getApplyNo, vo.getApplyNo());
            boolean b2 = outpTreatRecService.update(outpTreatRecLambdaUpdateWrapper);
            // 修改门诊收费表收费状态标志
            OutpFeesMasterBo outpFeesMasterBo = new OutpFeesMasterBo();
            outpFeesMasterBo.setOrdersId(vo.getClinicOrdersId());
            outpFeesMasterBo.setChargeFlag(chargeFlag);
            outpFeesMasterService.updateChargeFlag(outpFeesMasterBo);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 检验确认（取消确认），修改状态
     *
     * @param bo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean labConfirmOk(LabApplyBo bo) {
        List<LabApplyVo> labApplyVos = baseMapper.selectVoList(Wrappers.<LabApply>lambdaQuery().in(LabApply::getId, bo.getIds()));
        labApplyVos.forEach(labApplyVo -> {
            baseMapper.update(null, Wrappers.<LabApply>lambdaUpdate()
                    .set(LabApply::getConfirmFlag, bo.getConfirmFlag())
                    .set(LabApply::getConfirmUser, StringUtils.equals(bo.getConfirmFlag(), BaseConstants.CONFIRM_FLAG.ISSUED)
                            ? LoginHelper.getUserId() : "")
                    .set(LabApply::getConfirmDate, StringUtils.equals(bo.getConfirmFlag(), BaseConstants.CONFIRM_FLAG.ISSUED) ?
                            DateUtils.getNowDate() : null)
                    .set(StringUtils.equals(bo.getConfirmFlag(), BaseConstants.CONFIRM_FLAG.UNISSUED),
                            LabApply::getCancelConfirmUser, LoginHelper.getUserId())
                    .set(StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.SIX),
                            LabApply::getChargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)
                    .eq(LabApply::getId, labApplyVo.getId())
            );
            labItemMapper.update(null, Wrappers.<LabItem>lambdaUpdate()
                    .set(LabItem::getConfirmFlag, bo.getConfirmFlag())
                    .set(StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.SIX),
                            LabItem::getChargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)
                    .eq(LabItem::getApplyId, labApplyVo.getId())
            );
            clinicOrdersMapper.update(null, Wrappers.<ClinicOrders>lambdaUpdate()
                    .set(ClinicOrders::getConfirmFlag, bo.getConfirmFlag())
                    .set(StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.SIX),
                            ClinicOrders::getChargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)
                    .eq(ClinicOrders::getId, labApplyVo.getClinicOrdersId())
            );
            clinicOrdersCostMapper.update(null, Wrappers.<ClinicOrdersCost>lambdaUpdate()
                    .set(ClinicOrdersCost::getConfirmFlag, bo.getConfirmFlag())
                    .set(StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.SIX),
                            ClinicOrdersCost::getChargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)
                    .eq(ClinicOrdersCost::getOrdersId, labApplyVo.getClinicOrdersId())
            );
            outpTreatRecMapper.update(null, Wrappers.<OutpTreatRec>lambdaUpdate()
                    .set(OutpTreatRec::getConfirmFlag, bo.getConfirmFlag())
                    .set(StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.SIX),
                            OutpTreatRec::getChargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)
                    .eq(OutpTreatRec::getClinicOrdersId, labApplyVo.getClinicOrdersId())
            );
            outpFeesDetailMapper.update(null, Wrappers.<OutpFeesDetail>lambdaUpdate()
                    .set(OutpFeesDetail::getConfirmFlag, bo.getConfirmFlag())
                    .set(StringUtils.equals(labApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.SIX),
                            OutpFeesDetail::getChargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)
                    .eq(OutpFeesDetail::getClinicOrderId, labApplyVo.getClinicOrdersId())
            );
        });
        return Boolean.TRUE;
    }
}
